#include "av.h"

extern
int lua_sws_context_new(lua_State *L) {
	int src_w = luaL_checkinteger(L, 1);
	int src_h = luaL_checkinteger(L, 2);
	enum PixelFormat src_pf = lua_check_pixel_format(L, 3);
	int dst_w = luaL_checkinteger(L, 4);
	int dst_h = luaL_checkinteger(L, 5);
	enum PixelFormat dst_pf = lua_check_pixel_format(L, 6);

	struct SwsContext * scale = sws_getContext(src_w, src_h, src_pf, dst_w, dst_h, dst_pf,
		SWS_SPLINE, NULL, NULL, NULL);
	if(!scale) {
		luaL_error(L, "allocation error");
		return 0;
	}
	lua_push_sws_context(L, scale);
	return 1;
}

static
int lua_sws_context_scale(lua_State * L) {
	struct SwsContext * scale;
	AVFrame * src, * dst;
	lua_check_sws_context(L, 1, &scale);
	lua_check_frame(L, 2, &src);
	lua_check_frame(L, 3, &dst);
	int start = luaL_checkinteger(L, 4);
	int height = luaL_checkinteger(L, 5);
	int result = sws_scale(scale, src->data, src->linesize,
		start, height, dst->data, dst->linesize);

	if (result < 0) {
		luaL_error(L, "error (%d) while rescaling", result);
	}
	return 0;
}

static
const struct luaL_reg sws_context_reg[] = {
	{"scale", lua_sws_context_scale},
	{NULL, NULL},
};

static
void lua_sws_context_destroy(void * data) {
	sws_freeContext( (struct SwsContext *) data);
}

DEFINE_TYPE_STRUCT(sws_context, struct SwsContext,
	LUA_OBJECT_SWS_CONTEXT_ID, lua_sws_context_destroy, sws_context_reg)

DEFINE_INDEX_HEADER(sws_context, struct SwsContext)
DEFINE_INDEX_TRAILER()

DEFINE_NEWINDEX_HEADER(sws_context, struct SwsContext)
DEFINE_NEWINDEX_TRAILER()

DEFINE_OBJECT_FUNCTIONS(sws_context, struct SwsContext)

